package com.example.test.shiro;

import com.example.test.agent.entity.Role;
import com.example.test.agent.entity.Route;
import com.example.test.agent.service.RoleService;
import com.example.test.agent.service.RouteService;
import com.example.test.shiro.jwt.JWTToken;
import com.example.test.shiro.jwt.JWTUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Service
public class MyRealm extends AuthorizingRealm {


    @Autowired
    private RoleService roleService;

    @Autowired
    private RouteService routeService;


    /**
     * 必须重写此方法，不然shiro会报错
     * @param token
     * @return
     */
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof JWTToken;
    }

    /**
     * 校验权限，只有需要校验权限的时候，才会用到该方法
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        Integer userId = (Integer) principalCollection.getPrimaryPrincipal();
        List<Role> roleList = roleService.findRoleByUserId(userId);

        Set<String> roles = new HashSet<>();
        Set<String> routeS = new HashSet<>();
        for(int i = 0 ; i < roleList.size() ; i ++ ){
            Role role = roleList.get(i);
            roles.add(role.getRoleName());
            String routes = role.getRoutes();
            String[] routeIds = routes.split(",");
            for(int index = 0 ; index < routeIds.length ; index ++ ){
                Route route = routeService.getById(routeIds[index]);
                routeS.add(route.getRoutePath());
            }
        }
        simpleAuthorizationInfo.addStringPermissions(routeS);
        simpleAuthorizationInfo.addRoles(roles);
        return simpleAuthorizationInfo;
    }

    /**
     * 验证用户是否登录， token是否合法
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        Integer userId;
        String token = (String) authenticationToken.getCredentials();
        userId = JWTUtils.getUserId(token);
        if(userId == null){
            throw new AuthenticationException("token非法");
        }
        if(!JWTUtils.verify(userId, "secret", token)){
            //过期凭证
            throw new ExpiredCredentialsException("Exception of expired credentials");
        }
        return new SimpleAuthenticationInfo(userId, token, getName());
    }
}
